home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\MENU.C < prev    next >
C/C++ Source or Header  |  1994-12-28  |  9KB  |  418 lines

  1. /*
  2.  * menu.c: stuff for the menu's..
  3.  *
  4.  * Written By Troy Rollo <troy@cbme.unsw.oz.au>
  5.  *
  6.  * Copyright(c) 1991/1992.
  7.  *
  8.  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
  9.  */
  10.  
  11. #ifndef lint
  12. static    char    rcsid[] = "@(#)$Id: menu.c,v 1.7 1994/07/02 02:32:13 mrg Stab $";
  13. #endif
  14.  
  15. #include "irc.h"
  16.  
  17. #include "menu.h"
  18. #include "list.h"
  19. #include "ircaux.h"
  20. #include "term.h"
  21. #include "window.h"
  22. #include "screen.h"
  23. #include "input.h"
  24. #include "vars.h"
  25. #include "output.h"
  26.  
  27. Menu    *MenuList = (Menu *) 0;
  28.  
  29. struct    OptionTableTag
  30. {
  31.     char    *name;
  32.     void    (*func)();
  33. };
  34.  
  35. typedef    struct    OptionTableTag OptionTable;
  36.  
  37. static    OptionTable    OptionsList[] =
  38. {
  39.     { "PREVIOUS",    menu_previous },
  40.     { "MENU",    menu_submenu },
  41.     { "EXIT",    menu_exit },
  42.     { "CHANNELS",    menu_channels },
  43.     { "COMMAND",    menu_command },
  44.     { (char *) 0,    (void (*) ()) 0}
  45. };
  46.  
  47. MenuOption *create_new_option()
  48. {
  49.     MenuOption *NewOption;
  50.  
  51.     NewOption = (MenuOption *) new_malloc(sizeof(MenuOption));
  52.     NewOption->Name = (char *) 0;
  53.     NewOption->Arguments = (char *) 0;
  54.     NewOption->Func = (void (*) ()) 0;
  55.     return NewOption;
  56. }
  57.  
  58. Menu    *create_new_menu()
  59. {
  60.     Menu    *NewMenu;
  61.  
  62.     NewMenu = (Menu *) new_malloc(sizeof(Menu));
  63.     NewMenu->Name = (char *) 0;
  64.     NewMenu->TotalOptions = 0;
  65.     NewMenu->Options = (MenuOption **) 0;
  66.     return NewMenu;
  67. }
  68.  
  69.  
  70. void    install_menu(NewMenu, TotalMade)
  71. Menu    *NewMenu;
  72. int    TotalMade;
  73. {
  74.     MenuOption **NewOptions;
  75.     int    i;
  76.  
  77.     if (!NewMenu)
  78.         return;
  79.     if (TotalMade != NewMenu->TotalOptions)
  80.     {
  81.         NewOptions = (MenuOption **) malloc(TotalMade *
  82.                             sizeof(MenuOption *));
  83.         for (i = 0; i < TotalMade; i++)
  84.             NewOptions[i] = NewMenu->Options[i];
  85.         new_free(&NewMenu->Options);
  86.         NewMenu->Options = NewOptions;
  87.         NewMenu->TotalOptions = TotalMade;
  88.     }
  89.     add_to_list(&MenuList, NewMenu);
  90.     say("Menu \"%s\" added", NewMenu->Name);
  91. }
  92.  
  93. void    load_menu(FileName)
  94. char    *FileName;
  95. {
  96.     FILE    *fp;
  97.     Menu    *NewMenu = NULL;
  98.     char    *line, *command;
  99.     int    linenum = 0;
  100.     int    CurTotal = 0;
  101.     char    *name, *func;
  102.     int    FuncNum;
  103.     MenuOption **NewOptions;
  104.     int    i;
  105.  
  106.     if ((fp = fopen(FileName, "r")) == (FILE *) 0)
  107.     {
  108.         say("Unable to open %s", FileName);
  109.         return;
  110.     }
  111.     while (fgets(buffer, BIG_BUFFER_SIZE, fp))
  112.     {
  113.         buffer[strlen(buffer)-1] = '\0';
  114.         linenum++;
  115.         line = buffer;
  116.         while (isspace(*line))
  117.             line++;
  118.         if (*line == '#' || !(command = next_arg(line, &line)))
  119.             continue;
  120.         if (!my_stricmp(command, "MENU"))
  121.         {
  122.             if (!line || !*line)
  123.             {
  124.                 put_it("Missing argument in line %d of %s",
  125.                         linenum, FileName);
  126.                 continue;
  127.             }
  128.             install_menu(NewMenu, CurTotal);
  129.             NewMenu = create_new_menu();
  130.             malloc_strcpy(&NewMenu->Name, line);
  131.         }
  132.         else if (!my_stricmp(command, "OPTION"))
  133.         {
  134.             if (!(name = new_next_arg(line, &line)) ||
  135.                 !(func = next_arg(line, &line)))
  136.             {
  137.                 say("Missing argument in line %d of %s",
  138.                         linenum, FileName);
  139.                 continue;
  140.             }
  141.             for (i=0; OptionsList[i].name; i++)
  142.                 if (!my_stricmp(func, OptionsList[i].name))
  143.                     break;
  144.             if (!OptionsList[i].name)
  145.             {
  146.                 say("Unknown menu function \"%s\" in line %d \
  147. of %s",
  148.                     func, linenum, FileName);
  149.                 continue;
  150.             }
  151.             FuncNum = i;
  152.             if (++CurTotal > NewMenu->TotalOptions)
  153.             {
  154.                 NewOptions = (MenuOption **)
  155.                     new_malloc(sizeof(MenuOption *) *
  156.                         (CurTotal+4));
  157.                 for (i = 0; i < NewMenu->TotalOptions; i++)
  158.                     NewOptions[i] = NewMenu->Options[i];
  159.                 new_free(&NewMenu->Options);
  160.                 NewMenu->Options = NewOptions;
  161.                 NewMenu->TotalOptions = CurTotal + 5;
  162.             }
  163.             NewMenu->Options[CurTotal-1] = create_new_option();
  164.             malloc_strcpy(&NewMenu->Options[CurTotal-1]->Name,
  165.                 name);
  166.             malloc_strcpy(&NewMenu->Options[CurTotal-1]->Arguments,
  167.                 line);
  168.             NewMenu->Options[CurTotal-1]->Func =
  169.                     OptionsList[FuncNum].func;
  170.         }
  171.         else
  172.             say("Unkown menu command in line %d of %s",
  173.                 linenum, FileName);
  174.     }
  175.     install_menu(NewMenu, CurTotal);
  176.     fclose(fp);
  177. }
  178.  
  179. int    ShowMenuByWindow(window, flags)
  180. Window    *window;
  181. int    flags;
  182. {
  183.     int    i;
  184.     int    largest;
  185.     int    NumPerLine;
  186.     int    len;
  187.     WindowMenu *menu_info;
  188.     Menu    *ThisMenu;
  189.     int    CursorLoc;
  190.  
  191.     menu_info = &window->menu;
  192.     ThisMenu = menu_info->menu;
  193.     CursorLoc = menu_info->cursor;
  194.     largest = 0;
  195.     for (i = 0; i < ThisMenu->TotalOptions; i++)
  196.         if ((len = strlen(ThisMenu->Options[i]->Name))>largest)
  197.             largest = len;
  198.     NumPerLine = (CO - CO % (largest + 3)) / (largest + 3);
  199.     menu_info->items_per_line = NumPerLine;
  200.     menu_info->lines = 0;
  201.     for (i = 0; i < ThisMenu->TotalOptions; i++)
  202.     {
  203.         if ((flags & SMF_ERASE) && !(i % NumPerLine) &&
  204.             !(flags & SMF_CALCONLY))
  205.         {
  206.             term_move_cursor(0, window->top + menu_info->lines);
  207.             term_clear_to_eol();
  208.         }
  209.         if ((i == CursorLoc || !(flags&SMF_CURSONLY)) &&
  210.             !(flags & SMF_CALCONLY))
  211.         {
  212.             if (i == CursorLoc && !(flags & SMF_NOCURSOR) &&
  213.                     current_screen->inside_menu == 1)
  214.                 term_standout_on();
  215.             else
  216.                 term_bold_on();
  217.             term_move_cursor((i % NumPerLine) * (largest + 3),
  218.                 window->top+menu_info->lines);
  219.             fwrite(ThisMenu->Options[i]->Name,
  220.                 strlen(ThisMenu->Options[i]->Name), 1, stdout);
  221.             if (i == CursorLoc && !(flags & SMF_NOCURSOR))
  222.                 term_standout_off();
  223.             else
  224.                 term_bold_off();
  225.         }
  226.         if (!((i + 1) % NumPerLine))
  227.             menu_info->lines++;
  228.     }
  229.     if (i % NumPerLine)
  230.         menu_info->lines++;
  231.     window->display_size = window->bottom - window->top - menu_info->lines;
  232.     if (window->cursor < 0)
  233.         window->cursor = 0;
  234.     fflush(stdout);
  235.     update_input(UPDATE_JUST_CURSOR);
  236.     return ThisMenu->TotalOptions;
  237. }
  238.  
  239. void    ListMenu(ThisMenu)
  240. Menu    *ThisMenu;
  241. {
  242.     int    i;
  243.     int    j;
  244.  
  245.     for (i = 0; i < ThisMenu->TotalOptions; i++)
  246.     {
  247.         for (j = 0; ThisMenu->Options[i]->Func != OptionsList[j].func;
  248.                 j++);
  249.             say("  %-10s\t%-10s\t%s", ThisMenu->Options[i]->Name,
  250.                 OptionsList[j].name,
  251.                 ThisMenu->Options[i]->Arguments?
  252.                 ThisMenu->Options[i]->Arguments:"");
  253.     }
  254. }
  255.  
  256. int    ShowMenu(Name)
  257. char    *Name;
  258. {
  259.     Menu    *ThisMenu;
  260.     Window    *window;
  261.     WindowMenu *menu_info;
  262.  
  263.     window = curr_scr_win;
  264.     menu_info = &window->menu;
  265.     ThisMenu = (Menu *) find_in_list(&MenuList, Name, 0);
  266.     if (!ThisMenu)
  267.     {
  268.         say("No such menu \"%s\"", Name);
  269.         return -1;
  270.     }
  271.     menu_info->cursor = 0;
  272.     menu_info->menu = ThisMenu;
  273.     return ShowMenuByWindow(window, SMF_CALCONLY);
  274. }
  275.  
  276. void    set_menu(Value)
  277. char    *Value;
  278. {
  279.     Window    *window;
  280.     WindowMenu *menu_info;
  281.     ShrinkInfo SizeInfo;
  282.  
  283.     window = curr_scr_win;
  284.     menu_info = &window->menu;
  285.     if (!Value)
  286.     {
  287.         window->display_size = window->bottom - window->top;
  288.         menu_info->menu = (Menu *) 0;
  289.         menu_info->lines = 0;
  290.         SizeInfo = resize_display(window);
  291.         redraw_resized(window, SizeInfo, 0);
  292.         update_input(UPDATE_JUST_CURSOR);
  293.         current_screen->inside_menu = -1;
  294.     }
  295.     else
  296.     {
  297.         if (ShowMenu(Value) == -1)
  298.         {
  299.             set_string_var(MENU_VAR, NULL);
  300.             return;
  301.         }
  302.         SizeInfo = resize_display(window);
  303.         redraw_resized(window, SizeInfo, 0);
  304.         ShowMenuByWindow(window, SMF_ERASE);
  305. /*
  306.         redraw_window(window);
  307.  */
  308.     }
  309. }
  310.  
  311. void    enter_menu()
  312. {
  313.     if (!curr_scr_win->menu.menu)
  314.         return;
  315.     current_screen->inside_menu = 1;
  316.     ShowMenuByWindow(curr_scr_win, SMF_CURSONLY);
  317. }
  318.  
  319.  
  320. void    menu_previous(args)
  321. char    *args;
  322. {
  323. }
  324.  
  325. void    menu_submenu(args)
  326. char    *args;
  327. {
  328. }
  329.  
  330. void    menu_exit(args)
  331. char    *args;
  332. {
  333.     current_screen->inside_menu = -1;
  334. }
  335.  
  336. void    menu_channels(args)
  337. char    *args;
  338. {
  339. }
  340.  
  341. void    menu_key(key)
  342. char    key;
  343. {
  344.     Window *window;
  345.     WindowMenu *menu_info;
  346.     Menu    *ThisMenu;
  347.  
  348.     window = curr_scr_win;
  349.     menu_info = &window->menu;
  350.     ThisMenu = menu_info->menu;
  351.     ShowMenuByWindow(window, SMF_CURSONLY | SMF_NOCURSOR);
  352.     switch(key)
  353.     {
  354.     case 'U':
  355.     case 'u':
  356.     case 'P':
  357.     case 'p':
  358.     case 'k':
  359.     case 'K':
  360.     case 'U' - '@':
  361.     case 'P' - '@':
  362.         menu_info->cursor-=menu_info->items_per_line;
  363.         break;
  364.     case 'n':
  365.     case 'd':
  366.     case 'j':
  367.     case 'N':
  368.     case 'D':
  369.     case 'J':
  370.     case 'D' - '@':
  371.     case 'N' - '@':
  372.         menu_info->cursor+=menu_info->items_per_line;
  373.         break;
  374.     case 'b':
  375.     case 'h':
  376.     case 'B':
  377.     case 'H':
  378.     case 'B' - '@':
  379.         menu_info->cursor--;
  380.         break;
  381.     case 'f':
  382.     case 'l':
  383.     case 'F':
  384.     case 'L':
  385.     case 'F' - '@':
  386.         menu_info->cursor++;
  387.         break;
  388.     case '\033':
  389.         break;
  390.     case '\r':
  391.     case '\n':
  392.         hold_mode((Window *) 0, OFF, 1);
  393.         break;
  394.     case ' ':
  395.     case '.':
  396.         current_screen->inside_menu = 0;
  397.         ThisMenu->Options[menu_info->cursor]->Func(
  398.             ThisMenu->Options[menu_info->cursor]->Arguments);
  399.         if (current_screen->inside_menu != -1)
  400.             current_screen->inside_menu = 1;
  401.         else
  402.             current_screen->inside_menu = 0;
  403.         return; /* The menu may not be here any more */
  404.     }
  405.     if (menu_info->cursor>=menu_info->menu->TotalOptions)
  406.         menu_info->cursor = menu_info->menu->TotalOptions - 1;
  407.     if (menu_info->cursor < 0)
  408.         menu_info->cursor = 0;
  409.     if (current_screen->inside_menu)
  410.         ShowMenuByWindow(window, SMF_CURSONLY);
  411. }
  412.  
  413. void    menu_command(args)
  414. char    *args;
  415. {
  416.     parse_line((char *) 0, args, empty_string, 0, 0);
  417. }
  418.